/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.firebird.base.orm;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.firebird.base.utils.DateUtil;

/**
 * @author qiuxj
 * @date 2009-11-14
 */
public class HibernateDaoGenerator {
	
	  private static String DEFAULT_FILE_COMMENT = "/**\n * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights reserved.\n * <a>http:// www.cqcis.com</a>\n */\n\n";

	  private static String DEFAULT_TYPE_COMMENT = "/**\n *@author Fb HibernateDaoGenerator create " + 
	    DateUtil.getToday() + "\n *\n */\n";

	  private static String DEFAULT_DAO_SUFFIX = "Dao";
	  private static String DEFAULT_BASE_DAO = "com.cqcis.base.orm.hibernate.EntityHibernateDao";
	  private static String DEFAULT_BASE_DAO_CLASS = "EntityHibernateDao";

	  private boolean overWrite = false;
	  private String fileComment = DEFAULT_FILE_COMMENT;
	  private String typeComment = DEFAULT_TYPE_COMMENT;
	  private List<String> pkgImports = new ArrayList();
	  private String sourcePath;
	  private String sourcePackage;
	  private String targetPackage;
	  private String targetPath;
	  private int subStart = 0;

	  public HibernateDaoGenerator() {
	  }

	  public HibernateDaoGenerator(String sourcePath, String sourcePackage, String targetPath, String targetPackage) {
	    this.sourcePath = sourcePath;
	    this.sourcePackage = sourcePackage;
	    this.targetPath = targetPath;
	    this.targetPackage = targetPackage;

	    targetPathCheck(targetPath);
	  }

	  public void generate() throws IOException {
	    if ((this.sourcePackage == null) || (this.sourcePath == null) || (this.targetPackage == null) || 
	      (this.targetPath == null)) {
	      throw new NullPointerException(
	        "The paramerts sourcePackage,sourcePath,targetPackage,targetPath must not be null.");
	    }

	    for (String className : getEntityClassNames(this.sourcePath)) {
	      StringBuffer content = new StringBuffer();
	      String fileName = className.substring(this.subStart, this.subStart + 1).toLowerCase() + 
	        className.substring(this.subStart + 1) + DEFAULT_DAO_SUFFIX;
	      content.append(this.fileComment);
	      content.append("package " + this.targetPackage + ";\n\n");
	      content.append("import " + DEFAULT_BASE_DAO + ";\n");
	      content.append("import " + this.sourcePackage + "." + className + ";\n\n");
	      content.append(this.typeComment);
	      content.append("public class " + fileName + " extends ");
	      content.append(DEFAULT_BASE_DAO_CLASS + "<" + className + ">{\n}\n");

	      generateClass(fileName, content.toString());
	    }
	  }

	  protected void targetPathCheck(String targetPath) {
	    if (targetPath == null) {
	      throw new NullPointerException("The param targetPath must not be null.");
	    }

	    File file = new File(targetPath);
	    file.mkdirs();
	  }

	  protected void generateClass(String fileName, String content) throws IOException {
	    File file = new File(this.targetPath + fileName + ".java");
	    if ((!(file.exists())) || (this.overWrite)) {
	      FileWriter writer = new FileWriter(file);
	      try {
	        writer.write(content);
	      } finally {
	        writer.close();
	      }
	    }
	  }

	  protected List<String> getEntityClassNames(String path) {
	    List list = new ArrayList();
	    File dir = new File(path);
	    if (dir.isDirectory()) {
	      File[] files = dir.listFiles();
	      for (int i = 0; i < files.length; ++i) {
	        File file = files[i];
	        if (!(file.isDirectory())) {
	          list.add(file.getName().split(".java")[0]);
	        }
	      }
	    }

	    return list;
	  }

	  public String getFileComment()
	  {
	    return this.fileComment;
	  }

	  public void setFileComment(String fileComment) {
	    this.fileComment = fileComment;
	  }

	  public String getTypeComment() {
	    return this.typeComment;
	  }

	  public void setTypeComment(String typeComment) {
	    this.typeComment = typeComment;
	  }

	  public List<String> getPkgImports() {
	    return this.pkgImports;
	  }

	  public void setPkgImports(List<String> pkgImports) {
	    this.pkgImports = pkgImports;
	  }

	  public String getTargetPackage() {
	    return this.targetPackage;
	  }

	  public void setTargetPackage(String targetPackage) {
	    this.targetPackage = targetPackage;
	  }

	  public String getTargetPath() {
	    return this.targetPath;
	  }

	  public void setTargetPath(String targetPath) {
	    this.targetPath = targetPath;
	    targetPathCheck(targetPath);
	  }

	  public String getSourcePath() {
	    return this.sourcePath;
	  }

	  public void setSourcePath(String sourcePath) {
	    this.sourcePath = sourcePath;
	  }

	  public String getSourcePackage() {
	    return this.sourcePackage;
	  }

	  public void setSourcePackage(String sourcePackage) {
	    this.sourcePackage = sourcePackage;
	  }

	  public boolean isOverWrite() {
	    return this.overWrite;
	  }

	  public void setOverWrite(boolean overWrite) {
	    this.overWrite = overWrite;
	  }

	  public int getSubStart() {
	    return this.subStart;
	  }

	  public void setSubStart(int subStart) {
	    this.subStart = subStart;
	  }

}
